package cn.wolfcode.luowowo.search.service.impl;

import cn.wolfcode.luowowo.search.domain.StrategyTemplate;
import cn.wolfcode.luowowo.search.domain.UserInfoTemplate;
import cn.wolfcode.luowowo.search.qo.IndexSearchQo;
import cn.wolfcode.luowowo.search.qo.StrategySearchQo;
import cn.wolfcode.luowowo.search.repository.IStrategyTemplateRepository;
import cn.wolfcode.luowowo.search.repository.IUserInfoSearchRepository;
import cn.wolfcode.luowowo.search.service.ISearchService;
import cn.wolfcode.luowowo.search.service.IStrategyTemplateService;
import cn.wolfcode.luowowo.search.service.IUserInfoSearchService;
import cn.wolfcode.luowowo.search.vo.SearchStaticsVo;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.query.TermsQueryBuilder;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.bucket.composite.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;

import java.util.*;

@Service
public class StrategyTemplateServiceImpl implements IStrategyTemplateService {

    @Autowired
    private IStrategyTemplateRepository repository;
    @Reference
    private ISearchService searchService;

    @Override
    public void save(StrategyTemplate template) {
        repository.save(template);
    }

    @Override
    public List<Map<String, Object>> getTop10ThemeList() {

        List<SearchStaticsVo> list = getListByEs("themeId", "themeName");
        List<Map<String,Object>> resultList=new ArrayList<>();
            //设置map
        for (SearchStaticsVo staticsVo : list) {
            Map<String,Object> map=new HashMap<>();
            map.put("theme",staticsVo);
            List<SearchStaticsVo> dests = this.findDestsByThemeId(staticsVo.getId());
            map.put("dests",dests);
            resultList.add(map);
        }
        return resultList;
    }

    @Override
    public List<SearchStaticsVo> getListByEs(String id_str, String name_str) {
        //先拼接查询条件 多列分组查结果  多列分组
        List<CompositeValuesSourceBuilder<?>> sources=new ArrayList<>();
        TermsValuesSourceBuilder nammSource=new TermsValuesSourceBuilder("name");
        nammSource.field(name_str);
        sources.add(nammSource);
        TermsValuesSourceBuilder idSource=new TermsValuesSourceBuilder("id");
        idSource.field(id_str);
        sources.add(idSource);
        CompositeAggregationBuilder aggregationBuilder=new CompositeAggregationBuilder("themeGroup",sources);
        NativeSearchQueryBuilder builder=new NativeSearchQueryBuilder();
        builder.addAggregation(aggregationBuilder);
        builder.withPageable(PageRequest.of(0,1));

        AggregatedPage<StrategyTemplate> search = (AggregatedPage<StrategyTemplate>) repository.search(builder.build());

        InternalComposite themeGroup = search.getAggregations().get("themeGroup");
        //结果可以得到 themeId , themeName , count
        //通过调方法得到 list<sv>  一个个封装成map<>(三个键？ count 怎么放)  再扔进list
        List<SearchStaticsVo> list=new ArrayList<>();
        for (CompositeAggregation.Bucket internalBucket : themeGroup.getBuckets()) {
            Long id = Long.parseLong(internalBucket.getKey().get("id").toString());
            String name = internalBucket.getKey().get("name").toString();
            Long count = internalBucket.getDocCount();
            list.add(new SearchStaticsVo(id,name,count));
        }
        //集合的排序方法  给list<Map<>>  排序 能选用 map某个key 吗  如何选
        Collections.sort(list, new Comparator<SearchStaticsVo>() {
            @Override
            public int compare(SearchStaticsVo o1, SearchStaticsVo o2) {
                Long result=o2.getCount()-o1.getCount();
                return result.intValue();
            }
        });
        if(list.size()>10) {
            list=list.subList(0,10);
        }
        return list;
    }

    @Override
    public Page queryByDifferentType(StrategySearchQo qo) {
        //条件： type(判断是否等于-1)  sort  page
        //分页 sort
        PageRequest pageRequest = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(), Sort.Direction.DESC,qo.getOrderBy());
        //查询条件
        if(qo.getType()!=-1) {
            TermQueryBuilder queryBuilder = QueryBuilders.termQuery(qo.getSearchCondition(), qo.getTypeValue());
                return repository.search(queryBuilder,pageRequest);
        }
        return repository.findAll(pageRequest);
    }

    @Override
    public Page queryWithHighlight(IndexSearchQo qo) {
        Page<StrategyTemplate> page = searchService.searchWithHighlight(qo.getIndex(), qo.getTrueType(), StrategyTemplate.class, qo, "title", "subTitle", "summary");
        return page;
    }


    //抽取一个获取 list <sv> 的方法
    //通过  themeId  去查 destId  destName  并封装进sv  在 一个个放进list返回
    public List<SearchStaticsVo> findDestsByThemeId(Long id) {
        List<SearchStaticsVo> list=new ArrayList<>();
        List<StrategyTemplate> templates = repository.findByThemeId(id);

        List<String> names=new ArrayList<>();
        for (StrategyTemplate template : templates) {
            String destName = template.getDestName();
            if(!names.contains(destName)) {
                list.add(new SearchStaticsVo(template.getId(),destName,null));
                names.add(destName);
            }
        }
        return list;
    }
}
